<template>
<div class="row">
  <my-add-ip-detail></my-add-ip-detail>
  <upload-file-detail 
    :accept="moduleOptions[moduleIndex].accept" 
    :check-file-name="moduleOptions[moduleIndex].checkFileName" 
    :upload-file-name="moduleOptions[moduleIndex].uploadFileName" 
    :concurrency="concurrency"></upload-file-detail>
  <div class="col-md-12">
    <my-navbar fixed="top">
      <template slot="left">
        <select class="form-control" v-model="moduleIndex" @change.prevent="onModuleChange">
          <option v-for="option in moduleOptions" :value="$index">{{option.text}}</option>
        </select>             
        <button class="btn btn-default" @click.prevent="onScan">
          <span class="glyphicon glyphicon-plus"></span> {{$t("common.scan")}}
        </button>
        <select class="form-control" v-model="concurrency" number>
          <option v-for="option in concurrencyOptions">{{option}}</option>
        </select> 
        <span class="control-label">{{$t("common.concurrency")}}</span>
        <button class="btn btn-default" @click.prevent="onUpgrade">
          <span class="glyphicon glyphicon-open"></span> {{$t("common.upgrade")}}
        </button>     
      </template>
    </my-navbar>
  </div>
  <div class="col-md-12">
    <my-table :cfg="cfg" :list="orderList" :loading="false"></my-table>
  </div>
</div>
</template>

<script>
import _ from 'lodash'
import async from 'async'
import ebus from 'libs/ebus.js'
import toast from 'libs/toast.js'
import msgbox from 'libs/msgbox.js'
import {http} from 'share/common/api.js'
import UploadFileDetail from './UploadFileDetail.vue'

export default {
  components: {
    'upload-file-detail': UploadFileDetail
  },
  data () {
    return {
      scanDevCnt: 0,
      concurrency: 5,
      concurrencyOptions: [1, 3, 5, 10, 15, 20, 25, 30],
      moduleIndex: 0,
      minSize: 1*1024*1024,
      maxSize: 256*1024*1024, 
      moduleOptions: [{
        port: 8080,
        text: 'FOUNDER-100E/D/ES/DS',
        test: /^codec\.founder100/,
        accept: '.tar',
        checkFileName: this.checkFileNameOfFounder,
        uploadFileName: 'firmware.tar',
        updateCmd: {
          uri: '/dev/sys/cmd',
          body: {
            action: 'restart'
          }
        },
        stepUpdateState: this.stepUpdateStateOfCodec
      }, {
        port: 9080,
        text: 'M-CT-SERVER',
        test: /^server\.main\.pc/,
        accept: '.tar.gz',
        checkFileName: this.checkFileNameOfCT,
        uploadFileName: 'CenterServer.tar.gz',
        updateCmd: {
          uri: '/devs/0/sys/cmd',
          body: {
            action: 'updateSoftware',
            paramlist: {
              fileName: '/opt/upgrade/CenterServer.tar.gz'
            }
          }
        }
      }, {
        port: 6080,
        text: 'M-MD-SERVER',
        test: /^server\.media\.pc/,
        accept: '.tar.gz',
        checkFileName: this.checkFileNameOfMD,
        uploadFileName: 'MediaServer.tar.gz',
        updateCmd: {
          uri: '/dev/record/cmd',
          body: {
            action: 'updateSoftware',
            paramlist: {
              fileName: '/opt/upgrade/MediaServer.tar.gz'
            }
          }
        }
      }],
      cfg: {
        checkable: true,
        showHead: true,
        columns: [{
          field: 'ipaddr',
          width: '10%',
          name: 'IP'
        }, {
          field: 'devModel',
          width: '10%',
          name: 'DevModel'        
        }, {
          field: 'softwareVersion',
          width: '10%',
          name: 'Version'        
        }, {
          field: 'stage',
          width: '10%',
          name: 'Stage'        
        }, {
          field: 'progress',
          width: '10%',
          name: 'Progress'        
        }, {
          field: 'status',
          width: '40%',
          name: 'Status'        
        }, {
          field: 'result',
          width: '10%',
          name: 'Result'        
        }]
      },
      list: []
    }
  },
  computed: {
    orderList () {
      return _.orderBy(this.list, ['ipaddr'], ['asc'])
    }
  },
  methods: {
    checkFileNameOfFounder (name) {
      return name.startsWith('found100_main')
    },
    checkFileNameOfCT (name) {
      return name.startsWith('MainServer')
    },
    checkFileNameOfMD (name) {
      return name.startsWith('StreamServer')
    },
    tryConnectWsReport (wsUrl, task, cb) {
      var dev = task.dev
      var cbMsg = 'error'
      dev.progress++
      clearTimeout(dev.timer)
      var ws = new WebSocket(wsUrl, ['chat'])
      ws.onopen = function() {
        let req = {
          authType: 'upgrade',
          authCode: 'tendzone'
        }
        dev.stage = 'connected'
        ws.send(JSON.stringify(req))
      }.bind(this)
      ws.onmessage = function(e) {
        let msg = JSON.parse(e.data)
        if (msg.URI === '/api/sys/upgrade/progress') {
          if (msg.body.status === 0) {
            dev.stage = msg.body.stage
            dev.progress = msg.body.progress
            console.log(dev.ipaddr + ':' + msg.body.statusDesc)
            if (dev.progress >= 100) {
              dev.stage = 'end'
              cbMsg = 'finished'
            }
          } else {
            cbMsg = `${msg.body.status} ${msg.body.statusDesc}`
            ws.close()
          }
        }
      }.bind(this)
      ws.onclose = function(e) {
        if (dev.stage !== 'rebooting') {
          cb({msg: cbMsg})
        }
      }.bind(this)
      ws.onerror = function() {
        //var date = new Date()
        //console.log(date.toString() + ':error')
        if (dev.stage === 'rebooting') {
          dev.timer = setTimeout(function() {
            this.tryConnectWsReport(wsUrl, task, cb)
          }.bind(this), 2000)    
        }
      }.bind(this)      
    },
    stepUpdateStateOfCodec(host, task, cb) {
      var dev = task.dev
      let wsUrl = `ws://${dev.ipaddr}:8080/websocket/report`
      dev.stage = 'rebooting'
      dev.progress = 1
      dev.timer = setTimeout(function() {
        this.tryConnectWsReport(wsUrl, task, cb)
      }.bind(this), 10000)
    },    
    onModuleChange () {
      this.list.splice(0, this.list.length)
    },
    onScan () {
      ebus.emit('show-add-ip-detail')
    },
    onUpgrade () {
      var devs = _.filter(this.list, {_checked: true})
      if (devs.length <= 0) {
        toast.e(this, this.$t('common.fail'), this.$t('error.unselected'))
        return
      }
      ebus.emit('show-upload-file-detail', {
        module: this.moduleOptions[this.moduleIndex],
        devs: devs 
      })
    },
    scanDev (ipaddr, callback) {
      let module = this.moduleOptions[this.moduleIndex]
      let host = `http://${ipaddr}:${module.port}`
      let test = module.test

      http(host, '/api/platform/cfg', 'GET', null, {timeout: 1000})
      .then(function(res) {
        if (res && res.data && res.data.code === 0) {
          let platformInfo = res.data.data
          if (test.test(platformInfo.devModel)) {
            this.list.push({
              ipaddr: ipaddr,
              devModel: platformInfo.devModel,
              softwareVersion: platformInfo.softwareVersion,
              stage: '',
              progress: 0,
              status: '',
              result: '',
              _checked: false
            }) 
            this.scanDevCnt++         
          }
        }
        callback()
      }.bind(this), function(res) {
        callback()
      })
    },
    onAddIp (ipList) {
      if (ipList.length > 15) {
        msgbox.showWait(this.$t('alert.plzWait'), this.$t('common.processing'), -1)
      }
      this.scanDevCnt = 0
      async.eachLimit(ipList, 15, function(item, callback) {
        let dev = _.find(this.list, {ipaddr: item})
        if (dev) {
          callback()
          return
        }
        this.scanDev(item, callback)
      }.bind(this), function(err) {
        if (ipList.length > 15) {
          msgbox.close()
        }
        if (this.scanDevCnt > 0) {
          toast.s(this, this.$t('common.finish'), this.$t('alert.findResult', {cnt: this.scanDevCnt}))
        } else {
          toast.w(this, this.$t('common.finish'), this.$t('error.notFound'))
        }
      }.bind(this))
    }
  },
  ready () {
    ebus.on('add-ip', this.onAddIp)
    if (navigator.userAgent.indexOf("Chrome") !== -1) {
      msgbox.alert({
        title: this.$t('alert.browerNotSupport'),
        text: this.$t('alert.plzUseFirefox'),
        type: "warning",
        showCancelButton: false,
        confirmButtonColor: "#DD6B55",
        confirmButtonText: this.$t('common.confirm')     
      })
    }
  }
}
</script>

<style>
body { 
  padding-top: 70px; 
}
</style>